home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / System / scsi driver ƒ / SCSICmds.c < prev    next >
Encoding:
Text File  |  1989-04-14  |  8.6 KB  |  345 lines  |  [TEXT/KAHL]

  1. /*
  2. File SCSICmds.c, include file for SCSI.c
  3. Leo Drizis, March 1989
  4. Only for personal use, commercial use prohibited !!!
  5.  
  6. Contains all the basic SCSI Commands
  7. */
  8.  
  9. read(lblock,buffPtr,len)                    /* reads a sector from the disk */
  10. long lblock;                                                /* sector number */
  11. unsigned int len;                                /* length of sector in bytes */
  12. char *buffPtr;                                            /* pointer to data */
  13. {
  14. reWrCmd reCmd;
  15.  
  16. reCmd.opCode=0x8;                                    /* read command opcode */
  17. reCmd.rsrv1=lblock>>16;
  18. reCmd.addr=lblock&0xFFFF;
  19. reCmd.length=1;                                            /* read one sector */
  20. reCmd.rsrv2=0;
  21. err=SCSIGet();                            /* take the SCSI bus under control */
  22. ShowError("getting");
  23. if (err != 0) goto error;
  24. err=SCSISelect(SCSIid);                            /* select device to talk to */
  25. ShowError("selecting");
  26. if (err != 0) goto error;
  27. err=SCSICmd(&reCmd,sizeof(reCmd));                        /* send the command */
  28. ShowError("sending command");
  29. if (err != 0) goto error;
  30. readData(buffPtr,len);                                        /* read the data */
  31. if (err != 0) goto error;
  32. myComplete(TIMEOUT);                                /* complete the operation */
  33. ShowError("completing read");
  34. error:;
  35. }
  36.  
  37.  
  38. write(lblock,buffPtr,len)                            /* writes a sector to disk */
  39.                                         /* for other comments see read() above */
  40. long lblock;
  41. unsigned int len;
  42. char *buffPtr;
  43. {
  44. reWrCmd wrCmd;
  45.  
  46. wrCmd.opCode=0xA;
  47. wrCmd.rsrv1=lblock>>16;
  48. wrCmd.addr=lblock&0xFFFF;
  49. wrCmd.length=1;
  50. wrCmd.rsrv2=0;
  51. err=SCSIGet();
  52. ShowError("getting");
  53. if (err != 0) goto error;
  54. err=SCSISelect(SCSIid);
  55. ShowError("selecting");
  56. if (err != 0) goto error;
  57. err=SCSICmd(&wrCmd,sizeof(wrCmd));
  58. ShowError("sending command");
  59. if (err != 0) goto error;
  60. writeData(buffPtr,len);
  61. if (err != 0) goto error;
  62. myComplete(TIMEOUT);
  63. ShowError("completing write");
  64. error:;
  65. }
  66.  
  67.  
  68. readData(buffPtr, howMany)            /* reads data from drive during data phase */
  69. Ptr buffPtr;                                        /* pointer to store data */
  70. int howMany;                                        /* number of bytes to read */
  71. {
  72. myTIB[0].scOpcode=scNoInc;                    /* read without increasing pointer */
  73. myTIB[0].scParam1= (long) buffPtr;
  74. myTIB[0].scParam2=howMany;
  75. myTIB[1].scOpcode=scStop;                                    /* stop reading */
  76. myTIB[1].scParam1=0;
  77. myTIB[1].scParam2=0;
  78. #ifdef DEBUG
  79. printf("Reading data...\n");
  80. #endif
  81. if (BLIND) err=SCSIRBlind(myTIB);                                /* do the read */
  82.       else err=SCSIRead(myTIB);
  83. #ifdef DEBUG
  84. printf("Data read !\n");
  85. #endif
  86. ShowError("reading data");
  87. }
  88.  
  89.  
  90. writeData(buffPtr, howMany)            /* writes data to drive during data phase */
  91.                                     /* for other comments see readData() above */
  92. char *buffPtr;
  93. int howMany;
  94. {
  95. myTIB[0].scOpcode=scNoInc;
  96. myTIB[0].scParam1= (long) buffPtr;
  97. myTIB[0].scParam2=howMany;
  98. myTIB[1].scOpcode=scStop;
  99. myTIB[1].scParam1=0;
  100. myTIB[1].scParam2=0;
  101. #ifdef DEBUG
  102. printf("Writing data...\n");
  103. #endif
  104. if (BLIND) err=SCSIWBlind(myTIB);
  105.       else err=SCSIWrite(myTIB);
  106. #ifdef DEBUG
  107. printf("Data written, error = %d\n",err);
  108. #endif
  109. ShowError("writing data");
  110. }
  111.  
  112.  
  113. modSel(buff)                                    /* send a Mode Select Command */
  114.                 /* this command can change operating parameters in the drive */
  115. Ptr buff;                                            /* pointer to parameters */
  116. {
  117.  
  118. reWrCmd mdSlCmd;
  119.  
  120. mdSlCmd.opCode=0x15;                                /* opcode for the command */
  121. mdSlCmd.rsrv1=0;
  122. mdSlCmd.addr=0;
  123. mdSlCmd.length=12;                                            /* send 12 bytes */
  124. mdSlCmd.rsrv2=0;
  125. err=SCSIGet();
  126. ShowError("getting");
  127. if (err != 0) goto error;
  128. err=SCSISelect(SCSIid);
  129. ShowError("selecting");
  130. if (err != 0) goto error;
  131. err=SCSICmd(&mdSlCmd,sizeof(mdSlCmd));
  132. ShowError("sending mode select command");
  133. if (err != 0) goto error;
  134. writeData(buff,12);
  135. if (err != 0) goto error;
  136. myComplete(TIMEOUT);
  137. ShowError("completing mode select");
  138. error:;
  139. }
  140.  
  141.  
  142.  
  143. reqSen(buff)                                /* send a Request Sense command */
  144.                                     /* gets diagnostic error code from drive */
  145. Ptr buff;
  146. {
  147. reWrCmd rqSCmd;
  148.  
  149. rqSCmd.opCode=3;                                    /* opcode for the command */
  150. rqSCmd.rsrv1=0;
  151. rqSCmd.addr=0;
  152. rqSCmd.length=22;                            /* read 22 bytes of sense data */
  153. rqSCmd.rsrv2=0;
  154. err=SCSIGet();
  155. ShowError("getting");
  156. if (err != 0) goto error;
  157. err=SCSISelect(SCSIid);
  158. ShowError("selecting");
  159. if (err != 0) goto error;
  160. err=SCSICmd(&rqSCmd,sizeof(rqSCmd));
  161. ShowError("sending reqSense command");
  162. if (err != 0) goto error;
  163. readData(buff,22);
  164. if (err != 0) goto error;
  165. myComplete(TIMEOUT);
  166. ShowError("completing reqSense");
  167. error:;
  168. }
  169.  
  170.  
  171. modeSen(buff,page,len)                            /* send a Mode Sense command */
  172.                 /* with this command the drive reports its device parameters */
  173. Ptr buff;                                    /* pointer to receive the data */
  174. unsigned char page;                    /* number of parameter page to ask for */
  175. unsigned int len;                                /* number of bytes to read */
  176. {
  177. modeSenseCmd MSCmd;
  178.  
  179. MSCmd.opCode=0x1A;
  180. MSCmd.LUN=0;
  181. MSCmd.rsrv1=0;
  182. MSCmd.PCF=0;
  183. MSCmd.pageCode=page;
  184. MSCmd.rsrv2=0;
  185. MSCmd.allocLen=len;
  186. MSCmd.rsrv3=0;
  187. err=SCSIGet();
  188. ShowError("getting");
  189. if (err != 0) goto error;
  190. err=SCSISelect(SCSIid);
  191. ShowError("selecting");
  192. if (err != 0) goto error;
  193. err=SCSICmd(&MSCmd,sizeof(MSCmd));
  194. ShowError("sending modeSen command");
  195. if (err != 0) goto error;
  196. readData(buff,len);
  197. if (err != 0) goto error;
  198. myComplete(TIMEOUT);
  199. ShowError("completing modeSen");
  200. error:;
  201. }
  202.  
  203.  
  204. inquiry(buff,len)                                /* send an Inquiry command */
  205.         /* with this command the drive reports its non-changeable parameters */
  206. Ptr buff;                                    /* pointer to receive the data */
  207. unsigned int len;                                /* number of bytes to read */
  208. {
  209. modeSenseCmd inqCmd;
  210.  
  211. inqCmd.opCode=0x12;
  212. inqCmd.LUN=0;
  213. inqCmd.rsrv1=0;
  214. inqCmd.PCF=0;
  215. inqCmd.pageCode=0;
  216. inqCmd.rsrv2=0;
  217. inqCmd.allocLen=len;
  218. inqCmd.rsrv3=0;
  219. err=SCSIGet();
  220. ShowError("getting");
  221. if (err != 0) goto error;
  222. err=SCSISelect(SCSIid);
  223. ShowError("selecting");
  224. if (err != 0) goto error;
  225. err=SCSICmd(&inqCmd,sizeof(inqCmd));
  226. ShowError("sending inquiry command");
  227. if (err != 0) goto error;
  228. readData(buff,len);
  229. if (err != 0) goto error;
  230. myComplete(TIMEOUT);
  231. ShowError("completing inquiry");
  232. error:;
  233. }
  234.  
  235.  
  236. ReadDefect(buff,len)            /* reads the defect sector list from drive */
  237. Ptr buff;                                        /* pointer to receive the data */
  238. unsigned int len;                                    /* number of bytes to read */
  239. {
  240. readDefCmd RDCmd;
  241. unsigned long actLen;                        /* actual length of defects list */
  242.  
  243. Zero(&RDCmd,sizeof(RDCmd));
  244. RDCmd.opCode=0x37;
  245. RDCmd.which=0x18;            /* send manufacturer's and user defined defects */
  246. RDCmd.allocLen=4;                            /* send only the list header first */
  247. err=SCSIGet();
  248. ShowError("getting");
  249. if (err != 0) goto error;
  250. err=SCSISelect(SCSIid);
  251. ShowError("selecting");
  252. if (err != 0) goto error;
  253. err=SCSICmd(&RDCmd,sizeof(RDCmd));
  254. ShowError("sending read defect command");
  255. if (err != 0) goto error;
  256. readData(&actLen,4);
  257. if (err != 0) goto error;
  258. myComplete(TIMEOUT);
  259. ShowError("completing read defect");
  260. if (err != 0) goto error;
  261.  
  262. actLen &= 0x0000FFFF;                                    /* mask out the flags */
  263. actLen += 4;        /* and now we have the right length of the defects list */
  264. if (len > actLen) len = actLen;
  265. RDCmd.allocLen=len & 0x00FF;        /* this time read all of the defects list */
  266. err=SCSIGet();
  267. ShowError("getting");
  268. if (err != 0) goto error;
  269. err=SCSISelect(SCSIid);
  270. ShowError("selecting");
  271. if (err != 0) goto error;
  272. err=SCSICmd(&RDCmd,sizeof(RDCmd));
  273. ShowError("sending read defect command");
  274. if (err != 0) goto error;
  275. readData(buff,len);
  276. if (err != 0) goto error;
  277. myComplete(TIMEOUT);
  278. ShowError("completing read defect");
  279. error:;
  280. }
  281.  
  282.  
  283. Format()                                                /* formats the disk */
  284. {
  285. fmtCmd FCmd;
  286. unsigned int iL;                                        /* interleave value */
  287. char ans[20];
  288.  
  289. printf("Do you really want to format SCSI ID = %d [y/n] ? ",SCSIid);
  290. scanf("%s",ans);
  291. if (ans[0] != 'y' && ans[0] != 'Y') return;
  292. printf("Suggested interleave values :\n");
  293. printf("4 for Mac Plus\n");
  294. printf("3 for Mac SE\n");
  295. printf("1 for all 68020/68030 models\n");
  296. printf("Enter interleave value : ");
  297. scanf("%d",&iL);
  298. FCmd.opCode=0x4;
  299. FCmd.pars=0x00;            /* default format - retain previously defined defects */
  300. FCmd.rsrv1=0;
  301. FCmd.iLeave=iL&0xFF;
  302. FCmd.rsrv2=0;
  303. err=SCSIGet();
  304. ShowError("getting");
  305. if (err != 0) goto error;
  306. err=SCSISelect(SCSIid);
  307. ShowError("selecting");
  308. if (err != 0) goto error;
  309. err=SCSICmd(&FCmd,sizeof(FCmd));
  310. ShowError("sending format command");
  311. if (err != 0) goto error;
  312. printf("Now formatting, please wait...\n");
  313. myComplete(LONGWAIT);
  314. printf("Formatting ended !\n");
  315. ShowError("completing format");
  316. error:;
  317. }
  318.  
  319.  
  320.  
  321. long Capacity()                /* returns the capacity of the drive in sectors */
  322. {
  323. modeSenseCmd MSCmd;
  324.  
  325. Zero(&FPars,sizeof(FPars));
  326. MSCmd.opCode=0x1A;                                        /* mode sense command */
  327. MSCmd.LUN=0;
  328. MSCmd.rsrv1=0;
  329. MSCmd.PCF=0;
  330. MSCmd.pageCode=3;                                    /* ask for page three */
  331. MSCmd.rsrv2=0;
  332. MSCmd.allocLen=sizeof(FPars);                            /* no of bytes to ask */
  333. MSCmd.rsrv3=0;
  334. err=SCSIGet();
  335. if (err != 0) goto error;
  336. err=SCSISelect(SCSIid);
  337. if (err != 0) goto error;
  338. err=SCSICmd(&MSCmd,sizeof(MSCmd));
  339. if (err != 0) goto error;
  340. readData(&FPars,sizeof(FPars));
  341. myComplete(TIMEOUT);
  342. error:;
  343. return(FPars.blD.nBlocks);        /* return the size, or null if error occured */
  344. }
  345.